/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simpleGame.server;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.network.ConnectionListener;
import com.jme3.network.HostedConnection;
import com.jme3.network.Message;
import com.jme3.network.MessageListener;
import com.jme3.network.Network;
import com.jme3.network.Server;
import com.jme3.system.JmeContext;
import com.simsilica.es.EntityData;
import com.simsilica.es.EntityId;
import com.simsilica.es.net.EntitySerializers;
import com.simsilica.es.server.EntityDataHostService;
import de.tsajar.es.EntityDataAppState;
import de.tsajar.es.arrow.ArrowSystem;
import de.tsajar.es.character.CharacterControlSystem;
import de.tsajar.es.character.WalkDirectionComponent;
import de.tsajar.es.expiration.ExpirationSystem;
import de.tsajar.es.networking.server.EntityDataServerState;
import de.tsajar.es.physics.bullet.RigidBodyControlSystem;
import de.tsajar.es.render.RenderSystem;
import java.util.concurrent.atomic.AtomicInteger;
import modelinitializer.CubeInitializer;
import networked.Helper;
import networked.ShootMessage;
import simpleGame.ConnectionAcceptedMessage;
import simpleGame.WalkDirectionMessage;

/**
 *
 * @author eike
 */
public class Main extends SimpleApplication implements MessageListener<HostedConnection>, ConnectionListener {

    EntityData ed;
    EntityDataHostService edhs;

    public static void main(String[] args) {
        Main m = new Main();

        m.start(JmeContext.Type.Headless);
//        m.start();
    }

    private void initMyServer(int port) {

        Helper.initSerializers();
        try {
            Server s = Network.createServer(port);
            s.addConnectionListener(this);
            s.addMessageListener(this);
            s.start();
            s.addMessageListener(this, ShootMessage.class);
            stateManager.attach(new EntityDataServerState(s));
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    private void initPaulsServer(int port) {
        EntitySerializers.initialize();
        Helper.initSerializers();
        try {
            Server s = Network.createServer(port);
            s.addConnectionListener(this);
            s.addMessageListener(this);
            s.addChannel(1236);
            s.start();

            edhs = new EntityDataHostService(s, 0, ed);

            edhs.setAutoHost(true);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public void simpleInitApp() {

        BulletAppState bas = new BulletAppState();
        stateManager.attach(bas);
//        stateManager.attach(new BulletDebugAppState(bas.getPhysicsSpace()));

        stateManager.attach(new EntityDataAppState());
//        stateManager.attach(new DeviceInputSystem());
        stateManager.attach(new CharacterControlSystem());
        stateManager.attach(new RenderSystem(new CubeInitializer(assetManager)));
        stateManager.attach(new ArrowSystem(rootNode));
        stateManager.attach(new ExpirationSystem());
        stateManager.attach(new RigidBodyControlSystem());
        ed = stateManager.getState(EntityDataAppState.class).getEd();
        EntityFactory.ed = ed;
        initMyServer(1234);
//        initPaulsServer(1235);
        EntityFactory.addScene();
    }
    float tpc, tpu = 0.0001f;

    @Override
    public void simpleUpdate(float tpf) {
        tpc += tpf;
        if (tpc > tpu) {
            tpc = 0;
            if (edhs != null) {
                edhs.sendUpdates();
            }
        }
//        System.out.println(tpf);

    }

    public void messageReceived(HostedConnection source, Message m) {
        if (m instanceof ShootMessage) {
            ShootMessage sm = (ShootMessage) m;
            EntityFactory.fireArrow(sm.getPos(), sm.getDir());
        } else if (m instanceof WalkDirectionMessage) {
            ed.setComponent((EntityId) source.getAttribute("eId"), new WalkDirectionComponent(((WalkDirectionMessage) m).walkDirection));
        }
    }
    AtomicInteger inputIds = new AtomicInteger(0);

    public void connectionAdded(Server server, HostedConnection conn) {
        int inputId = inputIds.incrementAndGet();
        conn.setAttribute("eId", EntityFactory.addPlayer(inputId));
        conn.send(new ConnectionAcceptedMessage(inputId));
    }

    public void connectionRemoved(Server server, HostedConnection conn) {
        ed.removeEntity((EntityId) conn.getAttribute("eId"));
    }
}
